1
2
3
4 package joeq.Main;
5
6 import java.util.Iterator;
7 import joeq.Allocator.SimpleAllocator;
8 import joeq.Bootstrap.MethodInvocation;
9 import joeq.Class.PrimordialClassLoader;
10 import joeq.Class.jq_Class;
11 import joeq.Class.jq_NameAndDesc;
12 import joeq.Class.jq_StaticMethod;
13 import joeq.ClassLib.ClassLibInterface;
14 import joeq.Compiler.CompilationState;
15 import joeq.Compiler.CompilationState.DynamicCompilation;
16 import joeq.Runtime.Debug;
17 import joeq.Runtime.SystemInterface;
18 import joeq.Runtime.Unsafe;
19 import joeq.Scheduler.jq_InterrupterThread;
20 import joeq.Scheduler.jq_MainThread;
21 import joeq.Scheduler.jq_NativeThread;
22 import joeq.Scheduler.jq_Thread;
23 import joeq.UTF.Utf8;
24 import jwutil.strings.Strings;
25 import jwutil.util.Assert;
26
27 /***
28 * @author John Whaley <jwhaley@alum.mit.edu>
29 * @version $Id: JoeqVM.java 1941 2004-09-30 03:37:06Z joewhaley $
30 */
31 public abstract class JoeqVM {
32 public static void boot() throws Throwable {
33 try {
34
35 jq_NativeThread.initInitialNativeThread();
36
37
38 jq_NativeThread.initBreakThread();
39
40
41 CompilationState.DEFAULT = new DynamicCompilation();
42
43
44 ClassLibInterface.DEFAULT.initializeSystemClass();
45
46 } catch (Throwable x) {
47 SystemInterface.debugwriteln("Exception occurred during virtual machine initialization");
48 SystemInterface.debugwriteln("Exception: " + x);
49 if (System.err != null) x.printStackTrace(System.err);
50 return;
51 }
52
53 if (jq.on_vm_startup != null) {
54 Iterator it = jq.on_vm_startup.iterator();
55 while (it.hasNext()) {
56 MethodInvocation mi = (MethodInvocation) it.next();
57 try {
58 mi.invoke();
59 } catch (Throwable x) {
60 SystemInterface.debugwriteln("Exception occurred while initializing the virtual machine");
61 SystemInterface.debugwriteln(x.toString());
62 x.printStackTrace(System.err);
63
64 }
65 }
66 }
67
68 Debug.writeln("Joeq system initialized.");
69
70 int numOfArgs = SystemInterface.main_argc();
71 String[] args = new String[numOfArgs];
72 for (int i = 0; i < numOfArgs; ++i) {
73 int len = SystemInterface.main_argv_length(i);
74 byte[] b = new byte[len];
75 SystemInterface.main_argv(i, b);
76 args[i] = new String(b);
77 }
78 String classpath = ".";
79 int i = 0;
80 for (; ;) {
81 if (i == args.length) {
82 printUsage();
83 return;
84 }
85 if (args[i].equals("-cp") || args[i].equals("-classpath")) {
86 classpath = args[++i];
87 ++i;
88
89 if (classpath != null) {
90 Iterator it = PrimordialClassLoader.classpaths(classpath);
91 while (it.hasNext()) {
92 String s = (String) it.next();
93 PrimordialClassLoader.loader.addToClasspath(s);
94 }
95 }
96 continue;
97 }
98 if (args[i].equals("-nt") || args[i].equals("-native_threads")) {
99 jq.NumOfNativeThreads = Integer.parseInt(args[++i]);
100 ++i;
101 continue;
102 }
103 if (args[i].startsWith("-D")) {
104 String key;
105 String value;
106 int equals = args[i].indexOf('=');
107 if (equals != -1) {
108 key = args[i].substring(2, equals);
109 value = args[i].substring(equals+1);
110 } else {
111 key = args[i].substring(2);
112 value = "";
113 }
114 System.setProperty(key, value);
115 ++i;
116 continue;
117 }
118 if (args[i].startsWith("-mx")) {
119 String amt = args[i].substring(3);
120 int mult = 1;
121 if (amt.endsWith("m") || amt.endsWith("M")) {
122 mult = 1048576;
123 amt = amt.substring(0, amt.length()-1);
124 } else if (amt.endsWith("k") || amt.endsWith("K")) {
125 mult = 1024;
126 amt = amt.substring(0, amt.length()-1);
127 }
128 int size = mult * Integer.parseInt(amt);
129
130 SimpleAllocator.MAX_MEMORY = size;
131 ++i;
132 continue;
133 }
134
135 int j = TraceFlags.setTraceFlag(args, i);
136 if (i != j) {
137 i = j;
138 continue;
139 }
140 break;
141 }
142
143 handleSystemProperties();
144
145 jq_Thread tb = Unsafe.getThreadBlock();
146 jq_NativeThread nt = tb.getNativeThread();
147 jq_NativeThread.initNativeThreads(nt, jq.NumOfNativeThreads);
148
149
150 if (joeq.Class.jq_Class.TRACE_REPLACE_CLASS) SystemInterface.debugwriteln(Strings.lineSep+"STARTING REPLACEMENT of classes: " + joeq.Class.jq_Class.classToReplace);
151 for (Iterator it = joeq.Class.jq_Class.classToReplace.iterator(); it.hasNext();) {
152 String newCName = (String) it.next();
153 PrimordialClassLoader.loader.replaceClass(newCName);
154 }
155 if (joeq.Class.jq_Class.TRACE_REPLACE_CLASS) SystemInterface.debugwriteln(Strings.lineSep+"DONE with Classes Replacement!");
156
157 String className = args[i];
158 jq_Class main_class = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType("L" + className.replace('.', '/') + ";");
159 main_class.load();
160 jq_StaticMethod main_method = main_class.getStaticMethod(new jq_NameAndDesc(Utf8.get("main"), Utf8.get("([Ljava/lang/String;)V")));
161 if (main_method == null) {
162 System.err.println("Class " + className + " does not contain a main method!");
163 return;
164 }
165 if (!main_method.isPublic()) {
166 System.err.println("Method " + main_method + " is not public!");
167 return;
168 }
169 main_class.cls_initialize();
170 String[] main_args = new String[args.length - i - 1];
171 System.arraycopy(args, i + 1, main_args, 0, main_args.length);
172
173
174
175 jq_MainThread mt = new jq_MainThread(main_method, main_args);
176 mt.start();
177 jq_NativeThread.startNativeThreads();
178 nt.nativeThreadEntry();
179 Assert.UNREACHABLE();
180 }
181
182 public static void handleSystemProperties() {
183 String s;
184
185 s = System.getProperty("scheduler.quanta");
186 if (s != null) {
187 try {
188 jq_InterrupterThread.QUANTA = Integer.parseInt(s);
189 Debug.writeln("Scheduler quanta is ", jq_InterrupterThread.QUANTA);
190 } catch (NumberFormatException x) {
191 Debug.writeln("Bad scheduler.quanta, ignoring.");
192 }
193 }
194
195 s = System.getProperty("scheduler.transfer");
196 if (s != null) {
197 try {
198 jq_NativeThread.TRANSFER_THRESHOLD = Float.parseFloat(s);
199 Debug.write("Scheduler transfer threshold is ");
200 System.err.println(jq_NativeThread.TRANSFER_THRESHOLD);
201 } catch (NumberFormatException x) {
202 Debug.writeln("Bad scheduler.transfer, ignoring.");
203 }
204 }
205
206 s = System.getProperty("scheduler.stack");
207 if (s != null) {
208 try {
209 jq_Thread.INITIAL_STACK_SIZE = Integer.parseInt(s);
210 Debug.writeln("Thread stack size is ", jq_Thread.INITIAL_STACK_SIZE);
211 } catch (NumberFormatException x) {
212 Debug.writeln("Bad scheduler.stack, ignoring.");
213 }
214 }
215 }
216
217 public static void printUsage() {
218 System.out.println("Usage: joeq <classname> <parameters>");
219 }
220 }